package com.shchekoldin.server.service;

import com.shchekoldin.server.Application;
import com.shchekoldin.server.dto.MercurialBranchDto;
import com.shchekoldin.server.util.Configuration;
import org.apache.axis.utils.DefaultAuthenticator;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import sun.net.www.protocol.http.AuthCache;
import sun.net.www.protocol.http.AuthCacheValue;

import java.net.Authenticator;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MercurialService {

    private static final Pattern BRANCH_KEY_VALIDATE_PATTERN = Pattern.compile("^BUMP-[0-9]+$");

    public static final MercurialService INSTANCE = new MercurialService();

    /**
     * Disables global auth cache.
     * @see <a href="http://stackoverflow.com/questions/480895/reset-the-authenticator-credentials">Reset the Authenticator credentials</a>
     */
    private class DummyAuthCache implements AuthCache {

        @Override
        public void put(String s, AuthCacheValue authCacheValue) {
        }

        @Override
        public AuthCacheValue get(String s, String s1) {
            return null;
        }

        @Override
        public void remove(String s, AuthCacheValue authCacheValue) {
        }

    }

    // -------------------------------------------------------
    // LOGIC
    // -------------------------------------------------------

    private boolean validateKey(String key) {
        Matcher matcher = BRANCH_KEY_VALIDATE_PATTERN.matcher(key);
        return matcher.find();
    }
    
    private MercurialService() {
        AuthCacheValue.setAuthCache(new DummyAuthCache());
    }

    //
    // API
    //

    public List<MercurialBranchDto> run(int firstResult, int maxResults) throws Exception {
        Configuration config = Application.getConfiguration();

        Authenticator.setDefault(new DefaultAuthenticator(config.getMercurialUsername(), config.getMercurialPassword()));
        Document document = Jsoup.connect(config.getMercurialBranchesPageUrl()).get();
        Authenticator.setDefault(null);

        Elements branchesRows = document.select("tr.tagEntry");
        List<MercurialBranchDto> result = new ArrayList<MercurialBranchDto>();
        
        for (int i = firstResult; i < firstResult + maxResults; ++i) {
            Element branchRow = branchesRows.get(i);
            Element branchRowLink = branchRow.select("a").first();

            String key = branchRowLink.html();
            boolean keyValid = validateKey(key);
            String status = branchRowLink.attr("class");
            String lastRevision = branchRow.select("td.node").html();
            
            result.add(new MercurialBranchDto(key, keyValid, status, lastRevision));
        }

        return result;
    }

}
